

import UIKit
import SnapKit
import DZNEmptyDataSet

enum EmptyDataType {
    case base
    case onlyText
    case detail
}

class EmptyDataModel {
    var iconName: String?
    var text: String?
    var detailText: String?
    var ignoreOffset: Bool = false
    var offsetY: CGFloat = -navBarHeight * 0.5
    var addOffsetY: CGFloat = 0.0
}

protocol EmptyDataContentView where Self: UIView {
    var lastView: UIView? { get set}
    var emptyDataType: EmptyDataType? { get set }
    var emptyDataModel: EmptyDataModel? { get set }
}

class EmptyDataView: UIView, EmptyDataContentView {
    
    var emptyDataType: EmptyDataType? {
        didSet {
            resetLayout()
        }
    }
    var emptyDataModel: EmptyDataModel? {
        didSet {
            iconView.image = UIImage(named: emptyDataModel?.iconName ?? "")
            titleLabel.text = emptyDataModel?.text
            detailLabel.text = emptyDataModel?.detailText
        }
    }
    
    private lazy var iconView = UIImageView()
    private lazy var titleLabel = UILabel(text: "暂无数据".localizedString, font: UIFontMake(14), textColor: .white)
    private lazy var detailLabel = UILabel(font: UIFontMake(12), textColor: .white)
    
    var lastView: UIView?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        addSubview(iconView)
        addSubview(titleLabel)
        
        iconView.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.centerX.equalToSuperview()
        }
        
        titleLabel.snp.makeConstraints { make in
            make.top.equalTo(iconView.snp.bottom).offset(12)
            make.centerX.equalToSuperview()
        }
        
        lastView = titleLabel
        
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    private func resetLayout() {
  
        if emptyDataType == .onlyText {
            iconView.snp.remakeConstraints { make in}
            titleLabel.snp.remakeConstraints { make in
                make.top.equalToSuperview()
                make.centerX.equalToSuperview()
            }
            return
        }
        
        if emptyDataType == .detail {
            addSubview(detailLabel)
            lastView = detailLabel
            detailLabel.snp.makeConstraints { make in
                make.top.equalTo(titleLabel.snp.bottom).offset(8)
                make.centerX.equalToSuperview()
            }
        }
    }
    
}

class EmptyDataHandler: NSObject {
    
    weak var scrollView: UIScrollView?
    
    private(set) var dataModel: EmptyDataModel = EmptyDataModel()
    private var type: EmptyDataType = .base
    private var heightConstraint: NSLayoutConstraint!
    private(set) var emptyDataView: (UIView & EmptyDataContentView)?
    
    var display: Bool = false {
        didSet { scrollView?.reloadEmptyDataSet() }
    }
    
    init(scrollView: UIScrollView, makeEmptyView: (() -> (UIView & EmptyDataContentView))? = nil, configuration: ((EmptyDataModel) -> EmptyDataType)? = nil
    ) {
        super.init()

        self.scrollView = scrollView
        self.emptyDataView = makeEmptyView?()
        
        scrollView.emptyDataSetSource = self
        scrollView.emptyDataSetDelegate = self
        
        if let config = configuration {
            self.type = config(dataModel)
        } else {
            self.type = .base
        }
    }
}

extension EmptyDataHandler: DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
    
    func emptyDataSetShouldDisplay(_ scrollView: UIScrollView) -> Bool {
        return display
    }
    
    func verticalOffset(forEmptyDataSet scrollView: UIScrollView) -> CGFloat {
        if dataModel.ignoreOffset {
            return dataModel.offsetY
        }
        
        let contentInset = scrollView.contentInset
        if let tableView = scrollView as? UITableView, let headerView = tableView.tableHeaderView {
            return dataModel.offsetY + headerView.frame.height * 0.5 + contentInset.top + dataModel.addOffsetY
        }
        return dataModel.offsetY
    }
    
    func customView(forEmptyDataSet scrollView: UIScrollView) -> UIView? {
        
        var dataView: (UIView & EmptyDataContentView)!
        
        if let customEmptyView = emptyDataView {
            dataView = customEmptyView
        } else {
            dataView = EmptyDataView()
        }
        emptyDataView = dataView
        dataView.translatesAutoresizingMaskIntoConstraints = false
        heightConstraint = NSLayoutConstraint(item: dataView as Any, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 500
        )
        dataView.addConstraint(heightConstraint)
        return dataView
    }
    
    func emptyDataSetDidAppear(_ scrollView: UIScrollView) {
        
        guard let emptyDataView = emptyDataView else { return }
        
        emptyDataView.emptyDataModel = dataModel
        emptyDataView.emptyDataType = type
        
        guard let lastView = emptyDataView.lastView else {
            return
        }
        
        emptyDataView.superview?.setNeedsLayout()
        emptyDataView.superview?.layoutIfNeeded()
        
        heightConstraint.constant = CGRectGetMaxY(lastView.frame)
    }
    
    func backgroundColor(forEmptyDataSet scrollView: UIScrollView) -> UIColor! {
        return AppStyle.color.background
    }
    
    func emptyDataSetShouldAllowTouch(_ scrollView: UIScrollView) -> Bool {
        return true
    }
    
    func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView) -> Bool {
        return true
    }
}
